﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Filter;
using COFE.Data.Utils;

namespace COFE.Data
{
    public class DBEntryOperationProvider : IDBEntryOperationProvider
    {
        public IEnumerable<Entry> ReadEntries(COFEDB2 context, IEntryFilter[]
            entryFilters, IOptionFilter[] optionFilters)
        {
            IQueryable<Entry> queryable = context.Entries
            .Include("EntryProperties").AsQueryable<Entry>();
            foreach (var ef in entryFilters)
                queryable = DBFilterUtils.ProcessQuery(queryable, ef, optionFilters);
            foreach (var of in optionFilters)
                queryable = DBFilterUtils.ProcessQuery(queryable, of, optionFilters);


            IEnumerable<Entry> enumerable = from e in queryable select e;

            foreach (var ef in entryFilters)
                enumerable = DBFilterUtils.ProcessQueryOutput(enumerable, ef, optionFilters);
            foreach (var of in optionFilters)
                enumerable = DBFilterUtils.ProcessQueryOutput(enumerable, of, optionFilters);

            return enumerable;
        }


        #region ProcessQuery, ProcessQueryOutput
        private IQueryable<Entry> ProcessQuery(
            IQueryable<Entry> input, IFilter filter, IOptionFilter[] options)
        {
            var filterType = filter.GetType();

            if (filter is IEntryFilter)
            {
                var entryFilter = filter as IEntryFilter;
                var filterExpression = DBFilterUtils.GetFilterExpression(
                    entryFilter);
                if (filterExpression != null)
                    filterExpression.ProcessQuery(input,
                        entryFilter, options);
            }

            if (filter is IOptionFilter)
            {
                var optionFilter = filter as IOptionFilter;
                var filterExpression = DBFilterUtils.GetFilterExpression(
                    optionFilter);
                if (filterExpression != null)
                    filterExpression.ProcessQuery(input,
                        optionFilter, options);
            }
            return input;
        }

        private IEnumerable<Entry> ProcessQueryOutput(
            IEnumerable<Entry> input, IFilter filter, IOptionFilter[] options)
        {
            var filterType = filter.GetType();

            if (filter is IEntryFilter)
            {
                var entryFilter = filter as IEntryFilter;
                var filterExpression = DBFilterUtils.GetFilterExpression(
                    entryFilter);
                if (filterExpression != null)
                    filterExpression.ProcessQueryOutput(input,
                        entryFilter, options);
            }

            if (filter is IOptionFilter)
            {
                var optionFilter = filter as IOptionFilter;
                var filterExpression = DBFilterUtils.GetFilterExpression(
                    optionFilter);
                if (filterExpression != null)
                    filterExpression.ProcessQueryOutput(input,
                        optionFilter, options);
            }
            return input;
        }
        #endregion
    }
}
